// src/app.js - 重构后的完整应用实例，适合测试环境
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import bodyParser from "body-parser";
import morgan from "morgan";
import cookieParser from "cookie-parser";
import chalk from "chalk";
import * as Sentry from "@sentry/node";
import ratelimit from "express-rate-limit";
import Tracker from "bittorrent-tracker";

// 导入路由
import {
  accountRoutes,
  userRoutes,
  torrentRoutes,
  announcementRoutes,
  reportRoutes,
  adminRoutes,
  requestRoutes,
  groupRoutes,
  wikiRoutes,
} from "./routes";
import recommendationRouter from "./routes/recommendation";
import ratingRouter from "./routes/rating";

// 导入控制器
import {
  register,
  login,
  initiatePasswordReset,
  finalisePasswordReset,
  verifyUserEmail,
} from "./controllers/user";
import { downloadTorrent } from "./controllers/torrent";
import { rssFeed } from "./controllers/rss";

// 导入中间件
import auth from "./middleware/auth";
import behaviorCollector from "./middleware/behaviorCollector";
import createTrackerRoute from "./tracker/routes";

// 创建应用实例
const createApp = ({ tracker = null, mail = null } = {}) => {
  const app = express();
  
  // 基础设置
  app.set("trust proxy", true);
  app.disable("x-powered-by");

  // Sentry 初始化（仅在生产环境）
  if (process.env.SENTRY_DSN && process.env.NODE_ENV === "production") {
    Sentry.init({
      dsn: process.env.SENTRY_DSN,
      tracesSampleRate: 1.0,
      environment: process.env.NODE_ENV,
    });
  }

  // 日志中间件（测试环境简化）
  if (process.env.NODE_ENV === "test") {
    app.use(morgan("dev"));
  } else {
    const colorizeStatus = (status) => {
      if (!status) return "?";
      if (status.startsWith("2")) {
        return chalk.green(status);
      } else if (status.startsWith("4") || status.startsWith("5")) {
        return chalk.red(status);
      } else {
        return chalk.cyan(status);
      }
    };

    app.use(
      morgan((tokens, req, res) => {
        return [
          chalk.grey(new Date().toISOString()),
          chalk.magenta(req.headers["x-forwarded-for"] ?? req.ip),
          chalk.yellow(tokens.method(req, res)),
          tokens.url(req, res),
          colorizeStatus(tokens.status(req, res)),
          `(${tokens["response-time"](req, res)} ms)`,
        ].join(" ");
      })
    );
  }

  // 基础中间件
  app.use(cors());
  app.use(bodyParser.json({ limit: "5mb" }));
  app.use(cookieParser());

  // 限流（仅在生产环境）
  if (process.env.NODE_ENV === "production") {
    const limiter = ratelimit({
      windowMs: 1000 * 60,
      max: 120,
      keyGenerator: (req) => {
        if (
          req.headers["x-forwarded-for"] &&
          req.headers["x-sq-server-secret"] === process.env.SQ_SERVER_SECRET
        )
          return req.headers["x-forwarded-for"].split(",")[0];
        return req.ip;
      },
      skip: (req) => {
        return req.method === "OPTIONS";
      },
    });
    app.use(limiter);
  }

  // Tracker 路由（如果提供了 tracker）
  if (tracker) {
    const onTrackerRequest = tracker._onRequest?.bind(tracker);
    if (onTrackerRequest) {
      app.get("/sq/*/announce", createTrackerRoute("announce", onTrackerRequest));
      app.get("/sq/*/scrape", createTrackerRoute("scrape", onTrackerRequest));
    }
  }

  // 根路由
  app.get("/", (req, res) => {
    res.setHeader("Content-Type", "text/plain");
    res.send(`■ sqtracker running: ${process.env.SQ_SITE_NAME || 'Test Tracker'}`).status(200);
  });

  // 认证路由（不需要身份验证）
  app.post("/register", register(mail));
  app.post("/login", login);
  app.post("/reset-password/initiate", initiatePasswordReset(mail));
  app.post("/reset-password/finalise", finalisePasswordReset);
  app.post("/verify-email", verifyUserEmail);

  // RSS 和下载路由
  app.get("/rss", rssFeed(tracker));
  app.get("/torrent/download/:infoHash/:userId", downloadTorrent);

  // 认证中间件（所有后续路由都需要认证）
  app.use(auth);
  
  // 行为收集中间件（仅在生产环境）
  if (process.env.NODE_ENV !== "test") {
    app.use(behaviorCollector);
  }

  // API 路由
  app.use("/account", accountRoutes(tracker, mail));
  app.use("/user", userRoutes(tracker));
  app.use("/torrent", torrentRoutes(tracker));
  app.use("/announcements", announcementRoutes());
  app.use("/reports", reportRoutes());
  app.use("/admin", adminRoutes(tracker));
  app.use("/requests", requestRoutes());
  app.use("/group", groupRoutes());
  app.use("/wiki", wikiRoutes());
  app.use("/recommendation", recommendationRouter);
  app.use("/api/ratings", ratingRouter);

  // 错误处理中间件
  app.use((err, req, res, next) => {
    console.error(`[sq] error in ${req.url}:`, err);
    
    if (process.env.NODE_ENV === "test") {
      // 测试环境返回更详细的错误信息
      res.status(500).json({ 
        error: "Internal Server Error",
        message: err.message,
        stack: err.stack 
      });
    } else {
      res.status(500).send(`sqtracker API error: ${err.message}`);
    }
  });

  // 404 处理
  app.use((req, res) => {
    res.status(404).json({ error: "Not Found", path: req.path });
  });

  return app;
};

// 默认导出应用创建函数
export default createApp;

// 兼容性：也导出已创建的应用实例（用于测试）
export const app = createApp();